/**
 * @file Define the Qiniu service class
 * 
 * @author Steve Gao<gaofu@parlly.com>
 */

const qiniu         = require('qiniu');
const request       = require('request');

const utils         = require('../utils');
const BaseService   = require('./base-service').BaseService;

const {SystemServices, Configuration} = require('../constants');

/**
 * Wrap all methods about qiniu
 * 
 * @class QiniuService
 * @extends {BaseService}
 */
class QiniuService extends BaseService {
    
    get qiniuConfig() {
        if (!this._qiniuConfig) {
            this._qiniuConfig = this.getApplicationConfiguration(Configuration.QINIU);
        }

        return this._qiniuConfig;
    }

    get qiniuClient() {
        if (!this._qiniuClient) {
            let config = this.qiniuConfig;
            qiniu.conf.ACCESS_KEY = config.ak;
            qiniu.conf.SECRET_KEY = config.sk;
            this._qiniuClient = qiniu;
        }

        return this._qiniuClient;
    }

    getQiniuPath() {
        var date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        var day = date.getDate();
        var hour = date.getHours();
        var pathKey = '' + year + (month < 10 ? '0' + month : month) + (day < 10 ? '0' + day : day) + (hour < 10 ? '0' + hour : hour);

        return pathKey;
    }

    getFileKey(extName) {
        if (extName.indexOf(0) !== '.') {
            extName = `.${extName}`;
        }
        var fileKey = `${this.getQiniuPath()}/${utils.uuid()}${extName}`;
        return fileKey;
    }

    /**
     * Request Qiniu upload token
     * 
     * @name requestQiniuUptoken
     * @param {String} extName - The file extension name
     * 
     * @returns {String}
     */
    requestQiniuUptoken(extName) {
        var fileKey = this.getFileKey(extName);
        var bucket  = this.qiniuConfig.bucket;

        var putPolicy = new this.qiniuClient.rs.PutPolicy(`${bucket}:${fileKey}`);

        return {
            key: fileKey,
            token: putPolicy.token(),
            url: this.getCDNImageURL(fileKey)
        };
    }

    fetchURL(url, key, parentCallback) {
        var me = this;
        var client = new this.qiniuClient.rs.Client();
        client.fetch(url, this.qiniuConfig.bucket, key, (error, body, response) => {
            if (error) {
                me.logger.error(error);
            }
            parentCallback(body);
        });
    }

    fileStat(key, parentCallback) {
        var me = this;
        var client = new this.qiniuClient.rs.Client();
        client.stat(this.qiniuConfig.bucket, key, (error, body, response) => {
            if (error) {
                me.logger.error(error);
            }

            parentCallback(body);
        });
    }

    getImageInfo(url, parentCallback) {
        var me = this;
        var imageInfoURL = `${url}?imageInfo`;

        var options = {
            url: imageInfoURL,
            headers: {
                'Content-Type': 'application/json; charset=utf-8'
            }
        };

        request(options, (error, response, body) => {
            if (error) {
                me.logger.error(error);
            }
            var data = {};
            try {
                data = JSON.parse(body);
            } catch (e) {
                me.logger.error(`Error happened when parse JSON string [${body}]`, e);
            }
            parentCallback(data);
        });
    }
}

exports.QiniuService = QiniuService;